package com.ebupt.migu.music.unifyAudit.service.impl;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ebupt.migu.music.common.constants.StrategyConstants;
import com.ebupt.migu.music.market.entity.MarketSmsAudit;
import com.ebupt.migu.music.market.entity.MarketSmsInfo;
import com.ebupt.migu.music.market.entity.MarketSmsStrategy;
import com.ebupt.migu.music.market.mapper.MarketSmsAuditMapper;
import com.ebupt.migu.music.market.mapper.MarketSmsInfoMapper;
import com.ebupt.migu.music.market.mapper.MarketSmsStrategyMapper;
import com.ebupt.migu.music.market.service.impl.MarketSmsStrategyServiceImpl;
import com.ebupt.migu.music.strategy.mapper.StrategyMapper;
import com.ebupt.migu.music.unifyAudit.mapper.UnifyAuditMapper;
import com.ebupt.migu.music.unifyAudit.pojo.*;
import com.ebupt.migu.music.unifyAudit.service.UnifyAuditService;
import com.ebupt.migu.music.unifyAudit.util.ResultObject;
import com.ebupt.migu.music.userGroup.mapper.CrowdMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tz
 */
@Slf4j
@Service
public class UnifyAuditServiceImpl implements UnifyAuditService {

    @Value("${unifyAudit.appKey}")
    private String appKey;
    @Value("${unifyAudit.account}")
    private String account;
    @Value("${unifyAudit.auditSend}")
    private String auditSend;
    @Resource
    private UnifyAuditMapper unifyAuditMapper;
    @Resource
    private StrategyMapper strategyMapper;
    @Resource
    private CrowdMapper crowdMapper;
    @Resource
    private MarketSmsStrategyMapper marketSmsStrategyMapper;
    @Resource
    private MarketSmsAuditMapper marketSmsAuditMapper;
    @Resource
    private MarketSmsInfoMapper marketSmsInfoMapper;
    @Resource
    private MarketSmsStrategyServiceImpl marketSmsStrategyService;


    private Map<String, String> getAuthHeader() {
        Map<String, String> header = new HashMap<>(1);
        String timestamp = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String signature = DigestUtils.md5Hex(account + appKey + timestamp);
        header.put("Authorization", "authv1-" + account + "-" + timestamp + "-" + signature);
        log.info("鉴权header:{}", header);
        return header;
    }

    @Override
    public void auditSend(String strategyId, List<AuditData> data) {
        // 构建送审参数
        AuditReq req = AuditReq.builder().sources(data).type("text").manualAudit(true).account(account).notifyName("fine-operation-sms").build();
        // 发送请求
        log.info("送审参数：{}", req);
        String res = HttpRequest.post(auditSend).addHeaders(getAuthHeader()).body(JSON.toJSONString(req)).execute().body();
        log.info("送审返回结果：{}", res);
        ResultObject obj = JSON.parseObject(res, ResultObject.class);
        if ("000000".equals(obj.getCode())) {
            List<AuditDataResult> adr = JSONArray.parseArray(obj.getData().toString(), AuditDataResult.class);
            UnifyAudit ua = UnifyAudit.builder().strategyId(strategyId).build();
            adr.forEach(e -> {
                BeanUtils.copyProperties(e, ua);
                ua.setResultItems(Optional.ofNullable(e.getResultItems()).isPresent() ? JSON.toJSONString(e.getResultItems()) : null);
                unifyAuditMapper.insert(ua);
            });
        } else {
            log.info("送审返回失败！");
        }
    }

    @Override
    public Boolean isNext(String strategyId) {
        UnifyAudit ua = unifyAuditMapper.lastAudit(strategyId);
        return Optional.ofNullable(ua.getStatus()).isPresent() && ua.getStatus().equals(AuditStatus.ARTIFICIAL_PASS.getCode());
    }

    @Override
    public List<ResultVo> qryAudit(String strategyId) {
        List<UnifyAudit> unifyAudits = unifyAuditMapper.qryByStrategyId(strategyId);
        return unifyAudits.stream().map(e -> new ResultVo(AuditStatus.getNameByCode(e.getStatus()), Optional.ofNullable(e.getLabel()).isPresent() ? AuditResultType.getNameByCode(e.getLabel()) : "", e.getCreateTime(), Optional.ofNullable(e.getResultItems()).isPresent() ? getInfo(JSONArray.parseArray(e.getResultItems(), ResultItem.class)) : "")).sorted(Comparator.comparing(ResultVo::getAuditTime)).collect(Collectors.toList());
    }

    /**
     * 获取审核回调中不正常的文本
     *
     * @param items
     * @return
     */
    private String getInfo(List<ResultItem> items) {
        return items.stream().map(e -> e.getItems().stream().filter(f -> !f.getLabel().equals(AuditResultType.NORMAL.getCode())).map(Item::getSensitiveWord).collect(Collectors.joining(","))).collect(Collectors.joining(","));
    }


    @Override
    public ResultObject resultNotify(AuditDataResult result) {
        log.info("审核回执结果：{}", result);
        //审批记录
        String strategyId = result.getDataId().split("-")[0];
        UnifyAudit ua = UnifyAudit.builder().strategyId(strategyId).build();
        BeanUtils.copyProperties(result, ua);
        ua.setResultItems(Optional.ofNullable(result.getResultItems()).isPresent() ? JSON.toJSONString(result.getResultItems()) : null);
        unifyAuditMapper.insert(ua);
        // 人工审核通过
        if (result.getStatus().equals(AuditStatus.ARTIFICIAL_PASS.getCode())) {
            if (strategyId.startsWith("MS")) {
                // 挂机短信的业务
                handleCallerHungUpMessage(strategyId);
            } else {
                // 离线短信的业务
                handleOfflineSms(ua.getStrategyId());
            }
        }
        return new ResultObject().success();
    }

    /**
     * 统一审核回执特殊处理--离线短信
     */
    private void handleOfflineSms(String strategyId) {
        Map<String, Object> strategy = strategyMapper.queryByStrategyId(strategyId);
        // 客群小于200跳过审核
        HashMap<String, Object> userGroup = crowdMapper.queryByGroupID(strategy.get("groupId").toString());
        if (Integer.parseInt(userGroup.get("mobileUser").toString()) < 200) {
            strategyMapper.updateStatus(strategyId, StrategyConstants.EXECUTE_UNEXECUTED);
        }
        if (strategy.get("jobType").toString().equals("1")) {
            //立即执行策略
            if (!offset(String.valueOf(strategy.get("createTime")))) {
                log.info("是否结束任务:" + !offset(String.valueOf(strategy.get("createTime"))));
                strategyMapper.updateStatus(strategyId, StrategyConstants.EXECUTE_TERMINATED);
            }
        } else {
            //定时执行策略
            if (!offset(String.valueOf(strategy.get("startTime")))) {
                log.info("是否结束任务:" + !offset(String.valueOf(strategy.get("startTime"))));
                strategyMapper.updateStatus(strategyId, StrategyConstants.EXECUTE_TERMINATED);
            }
        }
    }

    // 挂机短信的审核流转控制
    private void handleCallerHungUpMessage(String strategyId) {
        // 当审核表中包含当前活动的记录时，将一级审核人的审核状态调整到待审核
        QueryWrapper<MarketSmsAudit> marketSmsAuditQueryWrapper = new QueryWrapper<>();
        marketSmsAuditQueryWrapper.eq("strategy_id", strategyId);
        boolean audit = marketSmsAuditMapper.exists(marketSmsAuditQueryWrapper);
        if (audit) {
            marketSmsAuditMapper.updatelevel1StatusByStrategyId("0", strategyId);
            return;
        }

        // 本系统没有审核流程时，代表客群规模在创建时预期小于200人。向大营销平台发起审核流程
        QueryWrapper<MarketSmsStrategy> marketSmsStrategyQueryWrapper = new QueryWrapper<>();
        marketSmsStrategyQueryWrapper.eq("strategy_id", strategyId);
        MarketSmsStrategy marketSmsStrategy = marketSmsStrategyMapper.selectOne(marketSmsStrategyQueryWrapper);

        QueryWrapper<MarketSmsInfo> marketSmsInfoQueryWrapper = new QueryWrapper<>();
        marketSmsInfoQueryWrapper.eq("strategy_id", strategyId);
        MarketSmsInfo marketSmsInfo = marketSmsInfoMapper.selectOne(marketSmsInfoQueryWrapper);
        try {
            // 向大营销平台发起审核
            marketSmsStrategyService.sendToMegamarketAudit(marketSmsStrategy, marketSmsInfo);
            // 将策略状态修改为等待大营销平台审核
            marketSmsStrategyMapper.updateExecuteStatusByStrategyId("9", strategyId);
        } catch (Exception e) {
            log.error("向大营销平台发起审核流程失败，策略ID：{}，异常信息：{}", strategyId, e.getMessage());
            e.printStackTrace();
        }
    }

    public boolean offset(String time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        boolean res = true;
        try {
            Date storedTime = sdf.parse(time);
            Date currentTime = new Date();
            long timeDiff = currentTime.getTime() - storedTime.getTime();
            long twentyFourHoursInMillis = 24 * 60 * 60 * 1000;
            if ((timeDiff >= twentyFourHoursInMillis)) {
                res = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }
}
